# -*- coding: utf-8 -*-

# === ユーザー招待コントローラ
class Common::InvitesController < ApplicationController
  skip_before_filter :login_required, :only => [:edit, :update]

  # === 招待画面のトップページ表示
  def index
    @invites = current_user.invites
  end

  # === 新規ユーザー招待メールの送信画面表示
  def new
    @invite = Invite.new(:inviter_name => current_user.nick_name,
                         :inviter_email => current_user.profile.email)
  end

  # === 招待者向けのトップページ表示
  # 招待メールのURLによって誘導されるページ。パラメータの招待コードの
  # チェックを行い、確認できなかった場合はリダイレクトでトップへ飛ばす
  # のではなく、単にfalseを返して何も情報を与えない。
  def edit
    @invite = check_invite_info(params[:id], params[:invite_code])
    return false unless @invite
    @account = User.new(:login => @invite.target_email)
    @invite_code = params[:invite_code]
    @invite_id   = params[:id]
  end

  # === 招待情報のDB保存＆招待メールの送信実行
  def create
    @invite = Invite.new(params[:invite])
    @invite.status = "inviting"
    @invite.user = current_user
    @invite.create_secret_code
    if @invite.save
      invite_url = edit_common_invite_url(@invite) + "?invite_code=#{@invite.secret_code}"
      if SnsMailer.invite_mail(@invite, invite_url).deliver
        redirect_to common_invites_path, :notice => "招待メールを送信しました。"
      else
        redirect_to common_invites_path, :notice => "招待メールの送信に失敗しました。"
      end
    else
      render :action => "new"
    end
  end

  # === 新規招待者のユーザー登録実行
  # メソッドが「update」なので紛らわしいが、新規ユーザーの登録である。
  # ここでも招待コードを確認して、招待者の本人認証を行っている。
  def update
    @invite_code = params[:invite_code]
    @invite_id   = params[:id]
    @account = User.new(params[:user])

    @invite = check_invite_info(params[:id], params[:invite_code])
    return false unless @invite

    begin
      ActiveRecord::Base.transaction do
        if @account.save
          @invite.status = "deleted"
          @invite.user.make_friend(@account)
          @invite.save

          setting = Setting.new(:message_format_type => "plain",
                                :blog_format_type => "markdown")
          setting.user = @account
          profile = Profile.new(:permissions => "none")
          profile.user = @account
          if setting.save && profile.save
            flash[:notice] = 'user created.'
            redirect_back_or_default "/"
          else
            raise ActiveRecord::Rollback
          end
        else
          render :action => "edit"
        end
      end
    rescue ActiveRecord::Rollback
      raise "アカウント登録に失敗しました。不明なエラーです。"
    end
  end

  # === 招待情報の破棄
  # TODO: システム管理者であれば他のユーザーのものでも破棄可能になるよう修正のこと
  def destroy
    @invite = Invite.find(params[:id])
    unless @invite.user == current_user
      redirect_to common_invites_path,
                   :notice => "削除権限がありません。"
      return false
    end
    @invite.status = "deleted"
    @invite.save
    redirect_to common_invites_path,
                 :notice => "招待をキャンセルしました。"
  end

  private

  # === 期待する招待情報が正しく存在しているか確認する
  def check_invite_info(id, invite_code)
    begin
      invite = Invite.find(id)
    rescue
      redirect_to "/", :notice => "招待情報が確認できませんでした。"
      return false
    end

    unless invite.secret_code == invite_code
      redirect_to "/", :notice => "招待コードが不正です。"
      return false
    end

    if invite.status == "deleted"
      redirect_to "/", :notice => "招待はキャンセルされています。"
      return false
    end
    return invite
  end
end
